package hamsterwrench.gui;

import hamsterwrench.data.reload.ReloadDataManager;
import hamsterwrench.data.reload.ReloadNode;
import hamsterwrench.data.reload.ReloadWrongTypeException;

import java.awt.BorderLayout;
import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.JOptionPane;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;

import com.jgoodies.forms.factories.FormFactory;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;

public class ReloadSpy extends JFrame implements TreeSelectionListener, Runnable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 8107193283824721799L;
	private JPanel contentPane;
	private JTextField reloadNodeName;
	private JTextField reloadNodeValue;
	private JTextField reloadNodeType;
	private JTree reloadTree;
	JFileChooser fc;
	private ReloadNode reloadNode;
	private problemCode pc = ReloadSpy.problemCode.OK;
	private DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Bad Data", false);

	/**
	 * Launch the application.
	 */
	/*public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ReloadSpy frame = new ReloadSpy();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}*/

	/**
	 * Create the frame.
	 */
	public ReloadSpy() {
		setIconImage(Toolkit.getDefaultToolkit().getImage(ReloadSpy.class.getResource("/assets/reloadicon.png")));
		setTitle("RELOAD Editor");
		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		setBounds(100, 100, 699, 377);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new BorderLayout(0, 0));

		JSplitPane splitPane = new JSplitPane();
		splitPane.setResizeWeight(0.25);
		contentPane.add(splitPane, BorderLayout.CENTER);

		JScrollPane scrollPane = new JScrollPane();
		splitPane.setLeftComponent(scrollPane);

		fc = new JFileChooser();
		int returnVal = fc.showOpenDialog(ReloadSpy.this);

		if(returnVal == JFileChooser.APPROVE_OPTION){
			reloadNode = ReloadDataManager.readReloadFile(fc.getSelectedFile());
			if(reloadNode == null) pc = ReloadSpy.problemCode.BAD_FILE;
			else rootNode = createNodes(reloadNode);
		}
		else pc = ReloadSpy.problemCode.USER_CANCEL;

		reloadTree = new JTree(rootNode);
		reloadTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
		reloadTree.addTreeSelectionListener(this);
		scrollPane.setViewportView(reloadTree);

		JPanel panel = new JPanel();
		splitPane.setRightComponent(panel);
		panel.setLayout(new FormLayout(new ColumnSpec[] {
				FormFactory.RELATED_GAP_COLSPEC,
				FormFactory.DEFAULT_COLSPEC,
				FormFactory.RELATED_GAP_COLSPEC,
				ColumnSpec.decode("default:grow"),},
				new RowSpec[] {
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,}));

		JLabel lblName = new JLabel("Name:");
		lblName.setHorizontalAlignment(SwingConstants.TRAILING);
		panel.add(lblName, "2, 2, right, default");

		reloadNodeName = new JTextField();
		reloadNodeName.setEditable(false);
		panel.add(reloadNodeName, "4, 2, fill, default");
		reloadNodeName.setColumns(10);

		JLabel lblType = new JLabel("Type:");
		lblType.setHorizontalAlignment(SwingConstants.TRAILING);
		panel.add(lblType, "2, 4");

		reloadNodeType = new JTextField("");
		reloadNodeType.setEditable(false);
		panel.add(reloadNodeType, "4, 4");

		JLabel lblValue = new JLabel("Value:");
		lblValue.setHorizontalAlignment(SwingConstants.TRAILING);
		panel.add(lblValue, "2, 6, right, default");

		reloadNodeValue = new JTextField();
		reloadNodeValue.setEditable(false);
		panel.add(reloadNodeValue, "4, 6, fill, default");
		reloadNodeValue.setColumns(10);

		JToolBar toolBar = new JToolBar();
		toolBar.setRollover(true);
		toolBar.setFloatable(false);
		contentPane.add(toolBar, BorderLayout.NORTH);

		JButton btnAddChild = new JButton("Add Child...");
		btnAddChild.setEnabled(false);
		toolBar.add(btnAddChild);

		JButton btnRemoveNode = new JButton("Remove Node");
		btnRemoveNode.setEnabled(false);
		toolBar.add(btnRemoveNode);

		toolBar.addSeparator();

		JButton btnSave = new JButton("Save");
		btnSave.setEnabled(false);
		toolBar.add(btnSave);


	}

	private DefaultMutableTreeNode createNodes(ReloadNode node){
		DefaultMutableTreeNode result = new DefaultMutableTreeNode(node);
		int children = node.getNumberOfChildren();
		for(int i = 0; i < children; i++){
			//System.out.println(i);
			result.add(createNodes(node.getChild(i)));
		}
		return result;

	}

	public problemCode hasProblem(){
		return pc;
	}

	@Override
	public void valueChanged(TreeSelectionEvent arg0) {
		DefaultMutableTreeNode selectedTreeNode = (DefaultMutableTreeNode) reloadTree.getLastSelectedPathComponent();
		if(selectedTreeNode == null) return; // no node selected, keep the last selected one up.
		ReloadNode node = (ReloadNode) selectedTreeNode.getUserObject();
		reloadNodeName.setText(node.getNodeName());
		try{
			switch(node.getType()){
			case NULL:
				reloadNodeType.setText("Null");
				reloadNodeValue.setText("(no value)");
				break;
			case BYTE:
				reloadNodeType.setText("8-bit integer");
				reloadNodeValue.setText(Short.toString(node.getByteData()));
				break;
			case SHORT:
				reloadNodeType.setText("16-bit integer");
				reloadNodeValue.setText(Short.toString(node.getShortData()));
				break;
			case INT:
				reloadNodeType.setText("32-bit integer");
				reloadNodeValue.setText(Integer.toString(node.getIntData()));
				break;
			case LONG:
				reloadNodeType.setText("64-bit integer");
				reloadNodeValue.setText(Long.toString(node.getLongData()));
				break;
			case FLOAT:
				reloadNodeType.setText("Double precision float");
				reloadNodeValue.setText(Double.toString(node.getFloatData()));
				break;
			case STRING:
				reloadNodeType.setText("String");
				reloadNodeValue.setText(node.getStringData());
				break;
			}
		}catch(ReloadWrongTypeException e){
			e.printStackTrace();
		}
	}
	
	public static enum problemCode{
		OK, BAD_FILE, USER_CANCEL
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		switch(pc){
		case OK:
			setVisible(true);
			break;
		case BAD_FILE:
			JOptionPane.showMessageDialog(ReloadSpy.this, "This doesn't appear to be a valid RELOAD file.", "ReloadSpy", JOptionPane.ERROR_MESSAGE);
			return;
		case USER_CANCEL:
			return;
		}
	}
}
